#!/usr/bin/envpython
# -*-coding:UTF-8-*-
'''
@File    :   win_fcntl_lock_helper.py
@Contact :   308711822@qq.com
@License :   (C) Copyright 2021-2225, Personal exclusive right.

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2023/6/9 9:57   小钟同学      1.0         None
'''
import os
import msvcrt
import win32file


class WinLock:
    def __init__(self, name):
        self.name = name
        self.handle = None
        self.acquired = False

    def acquire(self):
        if not self.acquired:
            path = os.getcwd()
            lockname = os.path.join(path, f"{self.name}.lock")
            try:
                self.handle = win32file.CreateFile(
                    lockname,
                    win32file.GENERIC_READ | win32file.GENERIC_WRITE,
                    0,
                    None,
                    win32file.OPEN_ALWAYS,
                    win32file.FILE_ATTRIBUTE_NORMAL,
                    None
                )
            except Exception as e:
                raise (e)

            flags = win32file.LOCKFILE_EXCLUSIVE_LOCK | win32file.LOCKFILE_FAIL_IMMEDIATELY
            try:
                win32file.LockFileEx(self.handle, flags, 0, -0x10000, win32file.PyOverlapped())
            except Exception as e:
                win32file.CloseHandle(self.handle)
                self.handle = None
                raise (e)

            self.acquired = True

    def release(self):
        if self.acquired:
            win32file.UnlockFileEx(self.handle, 0, -0x10000, win32file.PyOverlapped())
            win32file.CloseHandle(self.handle)
            self.handle = None
            self.acquired = False
            path = os.getcwd()
            lockname = os.path.join(path, f"{self.name}.lock")
            os.remove(lockname)

    def __enter__(self):
        self.acquire()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.release()
        return False

# lock = WinLock('my_lock_name')
# with lock:
#    # do something